package chapter10;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * 功能: FutureTask结构和源码分解.
 * 核心是：分析state的状态变化。最重点是什么时候是new状态：新建或task没有完完全全结束也是new状态
 * 1、run方法的流程，
 * 2、get方法的流程，涉及等待队列
 * 2、cancel方法的流程
 *
 * @author Fire Fish
 * @since 2022-08-09 9:53 AM
 */
public class FutureTaskTest {

    static Callable task1 = () -> {
        System.out.println("执行。。。。");

            for (int i=0;i<1000000;){
                System.out.println("执行。。。。");
                try { TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace(); }
            }

        return 1213;
    };

    public static void main(String[] args) {
        FutureTask<Void> futureTask = new FutureTask<>(task1);



    }

    /**
     * 演示了任务取消的情况：cancel只能取消new状态的任务（运行中也是new状态）
     * @param futureTask
     */
    private static void cancel_Test(FutureTask<Void> futureTask) {
        Thread thread = new Thread(() -> {
            try {
                futureTask.run();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        thread.start();


        new Thread(()->{
            try {
                System.out.println("开始取消");
                futureTask.cancel(false);
                System.out.println("取消完成");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();

        try { TimeUnit.SECONDS.sleep(1000);} catch (InterruptedException e) { e.printStackTrace(); }
    }

    /**
     * 演示了多个线程get进入阻塞队列的情况。
     * @param futureTask
     */
    private static void get_block_Test(FutureTask<Void> futureTask) {
        Thread thread = new Thread(() -> {
            try {
                futureTask.run();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        thread.start();

        // 多个线程等待获取结果造成FutureTask出现等待队列的情况：waiters
        new Thread(()->{
            try {
                futureTask.get();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();
        new Thread(()->{
            try {
                futureTask.get();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();
        new Thread(()->{
            try {
                futureTask.get();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();

        try { TimeUnit.SECONDS.sleep(1000);} catch (InterruptedException e) { e.printStackTrace(); }
    }
}





